package com.dib.neo.bkfs.fs;


import com.google.common.collect.Sets;

import java.io.IOException;
import java.nio.file.attribute.*;
import java.util.Map;
import java.util.Set;


class BKFileAttributeViews {

  static class Basic extends AbstractBasicFileAttributeView {

    protected final BKPath file;
    protected final boolean followLinks;

    Basic(BKPath file, boolean followLinks) {
      this.file = file;
      this.followLinks = followLinks;
    }

    @Override
    public BKFileAttributes readAttributes() throws IOException {
      //file.checkRead();
      BKFileAttributes attrs = file.getFileAttributes();
      return attrs;
    }

    @Override
    public void setTimes(FileTime lastModifiedTime,
        FileTime lastAccessTime,
        FileTime createTime) throws IOException {
      // null => don't change
      if (lastModifiedTime == null && lastAccessTime == null) {
        // no effect
        return;
      }

      // permission check
      //file.checkWrite();

    }
  }

  private static class BKFS extends Basic {

    private static final String MODE_NAME = "mode";
    private static final String INO_NAME = "ino";
    private static final String DEV_NAME = "dev";
    private static final String RDEV_NAME = "rdev";
    private static final String NLINK_NAME = "nlink";
    private static final String UID_NAME = "uid";
    private static final String GID_NAME = "gid";
    private static final String CTIME_NAME = "ctime";

    // the names of the unix attributes (including posix)
    static final Set<String> unixAttributeNames = Sets.union(basicAttributeNames,
        Sets.newHashSet(MODE_NAME, INO_NAME, DEV_NAME, RDEV_NAME,
            NLINK_NAME, UID_NAME, GID_NAME, CTIME_NAME));

    BKFS(BKPath file, boolean followLinks) {
      super(file, followLinks);
    }

    @Override
    public String name() {
      return "unix";
    }

    @Override
    public void setAttribute(String attribute, Object value)
        throws IOException {
      if (attribute.equals(MODE_NAME)) {
        //setMode((Integer)value);
        return;
      }

      super.setAttribute(attribute, value);
    }

    @Override
    public Map<String, Object> readAttributes(String[] requested)
        throws IOException {
      AttributesBuilder builder =
          AttributesBuilder.create(unixAttributeNames, requested);
      BKFileAttributes attrs = readAttributes();
        if (builder.match(MODE_NAME)) {
            builder.add(MODE_NAME, attrs.getMode());
        }
        if (builder.match(INO_NAME)) {
            builder.add(INO_NAME, attrs.getIno());
        }
        if (builder.match(DEV_NAME)) {
            builder.add(DEV_NAME, null);
        }
        if (builder.match(RDEV_NAME)) {
            builder.add(RDEV_NAME, null);
        }
        if (builder.match(NLINK_NAME)) {
            builder.add(NLINK_NAME, null);
        }
        if (builder.match(UID_NAME)) {
            builder.add(UID_NAME, attrs.getUid());
        }
        if (builder.match(GID_NAME)) {
            builder.add(GID_NAME, attrs.getGid());
        }
        if (builder.match(CTIME_NAME)) {
            builder.add(CTIME_NAME, attrs.creationTime());
        }
      return builder.unmodifiableMap();
    }
  }

  static Basic createBasicView(BKPath file, boolean followLinks) {
    return new BKFileAttributeViews.Basic(file, followLinks);
  }


  static BKFS createUnixView(BKPath file, boolean followLinks) {
    return new BKFS(file, followLinks);
  }


}
